import json
from datetime import datetime, timedelta
import time
import pytz
import requests
import urllib3

# 禁用HTTPS证书验证警告
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

from config import global_config
from sh_logger import logger


class Timer(object):
    def __init__(self, sleep_interval=0.5):
        self.ukey = global_config.getRaw('config', 'ukey')
        self.tokenid = global_config.getRaw('config', 'tokenid')
        self.productID = global_config.getRaw('config', 'product_id')
        #self.buy_time = datetime.strptime(global_config.getRaw('config', 'buy_time'), "%Y-%m-%d %H:%M:%S.%f")
        self.buy_time = self.get_buytime()
        # 购买时间的时间戳
        if self.buy_time is not None:
            self.buy_time_ms = int(time.mktime(self.buy_time.timetuple()) * 1000.0 + self.buy_time.microsecond / 1000)
        else:
            self.buy_time_ms = None
        self.sleep_interval = sleep_interval

        self.diff_time = self.local_sh_time_diff()

    def sh_time(self):
        """
        从搜货服务器获取时间戳
        """
        url = 'https://sapph5api.leqilucky.com/NoAuth/Product/GetCategoryLeve1'
        headers = {
            'accept': 'application/json, text/plain, */*',
            'User-Agent': global_config.getRaw('config', 'DEFAULT_USER_AGENT'),
            'origin': 'https://sapph5.lqlucky.com',
            'x-requested-with': 'com.tencent.mm',
            'sec-fetch-site': 'cross-site',
            'sec-fetch-mode': 'cors',
            'sec-fetch-dest': 'empty',
            'Referer': 'https://sapph5.lqlucky.com/',
            'accept-encoding': 'gzip, deflate',
            'accept-language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7'
        }
        payload = {
            "uname": 'h5',
            "ukey": self.ukey,
            "tokenid": self.tokenid
        }
        local_time = self.local_time()
        local_datetime = datetime.now()
        start_time = time.time()  # 记录开始时间
        resp = requests.get(url, verify=False, params=payload, headers=headers)
        end_time = time.time()  # 记录结束时间

        logger.info('请求服务器时间:{}'.format(resp.text))
        elapsed_time = (end_time - start_time) * 1000  # 计算延迟时间（毫秒）

        beijing_time, sh_timestamp = self.get_header_date(resp)

        time_diff = local_time - sh_timestamp
        logger.info('请求服务器延迟:{}毫秒，本地时间为：{}，服务器时间为：{}，时间差为：{}毫秒'.format(elapsed_time, local_datetime, beijing_time, time_diff))
        return sh_timestamp

    def get_header_date(self, resp):
        # Tue, 28 Nov 2023 23:57:00 GMT
        date_string = resp.headers.get('date')
        date_format = '%a, %d %b %Y %H:%M:%S %Z'
        # 将字符串解析为datetime对象
        dt = datetime.strptime(date_string, date_format)
        # 将datetime对象转换为UTC时间
        utc_time = pytz.utc.localize(dt)
        # 将UTC时间转换为北京时间
        beijing_time = utc_time.astimezone(pytz.timezone('Asia/Shanghai'))
        # 将北京时间转换为时间戳
        sh_timestamp = int(beijing_time.timestamp()) * 1000
        return beijing_time, sh_timestamp

    def local_time(self):
        """
        获取本地毫秒时间
        :return:
        """
        return int(round(time.time() * 1000))

    def local_sh_time_diff(self):
        """
        计算本地与搜货服务器时间差
        :return:
        """
        return self.local_time() - self.sh_time()

    def start(self):
        if self.buy_time_ms is None:
            logger.info('该商品暂无抢购时间，无法开始抢购')
            return
        logger.info('正在等待到达设定时间:{}，检测本地时间与搜货服务器时间误差为【{}】毫秒'.format(self.buy_time, self.diff_time))
        while True:
            # 本地时间减去与搜货的时间差，能够将时间误差提升到0.1秒附近
            # 具体精度依赖获取搜货服务器时间的网络时间损耗
            # if self.local_time() + self.diff_time >= self.buy_time_ms:
            if self.local_time() - self.diff_time >= self.buy_time_ms:
                logger.info('时间到达，开始执行……')
                break
            else:
                time.sleep(self.sleep_interval)

    def get_buytime(self):
        url = 'https://sapph5api.leqilucky.com/NoAuth/SaleIndex/SaleProductInfo'
        headers = {
            'accept': 'application/json, text/plain, */*',
            'User-Agent': global_config.getRaw('config', 'DEFAULT_USER_AGENT'),
            'origin': 'https://sapph5.lqlucky.com',
            'x-requested-with': 'com.tencent.mm',
            'sec-fetch-site': 'cross-site',
            'sec-fetch-mode': 'cors',
            'sec-fetch-dest': 'empty',
            'Referer': 'https://sapph5.lqlucky.com/',
            'accept-encoding': 'gzip, deflate',
            'accept-language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7'
        }
        payload = {
            "uname": 'h5',
            "ukey": self.ukey,
            "tokenid": self.tokenid,
            'productId': self.productID
        }
        resp = requests.get(url, verify=False, params=payload, headers=headers)
        data_dict = json.loads(resp.text)
        logger.info('请求商品详情:{}'.format(data_dict["SaleProductInfo"]["TitleShort"]))

        scareBuyNodeList = data_dict["SaleProductInfo"]["ScareBuyNodeList"]
        if scareBuyNodeList:
            # 将时间字符串解析为时间对象
            time_str = scareBuyNodeList[0].get('Node')
            time_obj = datetime.strptime(time_str, '%H:%M').time()
            # 获取今天的日期
            today = datetime.now()
            if time_str == '0:00':
                tomorrow = today + timedelta(days=1)
                sub_date = tomorrow.date()
            else:
                sub_date = today.date()
            # 将日期和时间合并
            combined_datetime = datetime.combine(sub_date, time_obj)
            # 添加毫秒
            milliseconds = 1
            combined_datetime_with_milliseconds = combined_datetime + timedelta(milliseconds=milliseconds)
            logger.info('抢购时间:{}'.format(combined_datetime_with_milliseconds))
            return combined_datetime_with_milliseconds
        else:
            logger.info('抢购时间:{}'.format(scareBuyNodeList))
            return None
